package top.java.multithreading;

/**
 *      多线程的创建      方式一：继承Thread类
 *
 *      1.创建一个类继承Thread类
 *      2.重写Thread类中的run方法
 *      3.创建Thread子类的对象并调用start()方法
 *
 *
 *        多线程的创建      方式二：实现Runnable
 *
 *        1.创建一个实现了Runnable接口的类
 *        2.实现类去实现Runnable中的抽象方法  run()
 *        3.创建实现类的对象
 *        4.将此对象作为参数传递到Thread类的构造器中，创建Thread类的对象
 *        5.通过Thread类的对象调用start()
 */

/**
 *       开发中优先实现Runnable的方式
 *       1.实现的方式没有类单继承的局限性
 *       2.实现的方式更适合来处理多个线程有共享数据的情况
 *
 *       两种方式的联系：Thread类也实现了Runnable接口
 */

/**
 *          IllegalThreadStateException异常       非法的线程状态
 *
 *     1. 同一个Thread不能重复调用start方法，跟线程的4中状态有关系
 *
 *     2. 线程的4种状态：新生状态；可运行状态；阻塞状态；死亡状态
 *
 *            a. 新生状态：在调用start()方法之前
 *
 *            b. 可运行状态：调用start()方法后，系统为该线程分配除cpu外的所需资源，对于只有一个cpu的机器而言，
 *            任何时刻只能有一个处于可运行的线程占用处理机，获得cpu资源，此时系统正正运行线程的run()方法....
 *
 *           c. 阻塞状态：一个正在运行的线程因某种原因不能继续运行时，进入阻塞状态。这是【不可运行】的状态，
 *           处于这种状态的线程在得到一个特定的事件后会转回可运行状态
 *
 *           d. 死亡状态：一个线程的run()运行完毕，stop()方法被调用或者在运行过程中出现了未捕获的异常时，
 *           线程进入死亡状态。
 *
 *      3. 线程的4中状态除了【可运行状态】与【阻塞状态】可以来回切换，其余的不可逆转
 *
 *
 *      正在运行的程序（软件）就是一个独立的进程， 线程是属于进程的，多个线程其实是并发与并行同时进行的。
 *
 *      进程
 *          概念：程序的一次执行过程，或是正在运行的一个程序。
 *          说明：进程作为资源分配的单位，系统在运行时会为每个进程分配不同的内存区域
 *
 *      线程
 *          概念：进程可进一步细化为线程，是一个程序内部的一条执行路径。
 *          说明：线程作为调度和执行的单位，每个线程拥独立的运行栈和程序计数器(pc)，线程切换的开销小。
 *
 *      并发：
 *          CPU同时处理线程的数量有限。
 *          CPU会轮询为系统的每个线程服务，由于CPU切换的速度很快，给我们的感觉这些线程在同时执行，这就是并发。
 *       并发：一个CPU同时执行多个任务。比如：秒杀、多个人做同一件事
 *
 *      并行：
 *          在同一个时刻上，同时有多个线程在被CPU处理并执行。
 *       并行：多个CPU同时执行多个任务。比如：多个人同时做不同的事。
 *
 *       并发：CPU分时轮询的执行线程。
 *       并行：同一个时刻同时在执行。
 *
 *       Java线程的状态
 *          Java总共定义了6种状态
 *          6种状态都定义在Thread类的内部枚举类中。
 *
 *  Thread.State枚举类中
 *
 *  NEW(新建)				    线程刚被创建，但是并未启动。
 *  Runnable(可运行)			    线程已经调用了start()等待CPU调度
 *  Blocked(锁阻塞)			    线程在执行的时候未竞争到锁对象，则该线程进入Blocked状态；
 *  Waiting(无限等待)			    一个线程进入Waiting状态，另一个线程调用notify或者notifyAll方法才能够唤醒
 *  Timed Waiting(计时等待)	    同waiting状态，几个方法超时参数，调用他们将进入Timed Waiting状态。带超时
 *                                  参数的常用方法Thread.sleep 、Object.wait。
 *  Teminated(被终止)			因为run方法正常退出而死亡，或者因为没有捕获的异常终止了run方法而死亡。
 *
 */


public class ThreadDemo {

    public static void main(String[] args) {
        /**
         *    多线程的创建      方式一：继承Thread类
         */
        MyThread myThread = new MyThread();
        myThread.start();
//        while (true) {
//            System.out.println("11111111111111" + Thread.currentThread().getName());
//            System.out.println("22222222222222" + Thread.currentThread().getName());
//            System.out.println("33333333333333" + Thread.currentThread().getName());
//        }

        /**
         *    多线程的创建      方式二：实现Runnable
         */
        //3.创建实现类的对象
        MyThread2 myThread2 = new MyThread2();
        // 4.将此对象作为参数传递到Thread类的构造器中，创建Thread类的对象
        Thread thread = new Thread(myThread2);
        //5.通过Thread类的对象调用start()
        thread.start();
        //再启动一个线程
        Thread thread2 = new Thread(myThread2);
        thread2.start();
    }

}

class MyThread extends Thread {

    @Override
    public void run() {

//        for (int i = 2;i <=1000;i++) {
//            boolean isFa = true;
//            for (int j = 2;j <= Math.sqrt(i);j++) {
//                if (i % j == 0) {
//                    isFa = false;
//                    break;
//                }
//            }
//            if (isFa) {
//                System.out.println(i);
//            }
//        }
        while (true) {
            System.out.println("11111111111111" + Thread.currentThread().getName());
            System.out.println("22222222222222" + Thread.currentThread().getName());
            System.out.println("33333333333333" + Thread.currentThread().getName());
        }
    }
}

/**
 *      多线程的创建      方式二：实现Runnable
 *
 *      1.创建一个实现了Runnable接口的类
 *      2.实现类去实现Runnable中的抽象方法  run()
 *      3.创建实现类的对象
 *      4.将此对象作为参数传递到Thread类的构造器中，创建Thread类的对象
 *      5.通过Thread类的对象调用start()
 */

class MyThread2 implements Runnable {

    @Override
    public void run() {
        for (int i = 2;i <=1000;i++) {
            boolean isFa = true;
            for (int j = 2;j <= Math.sqrt(i);j++) {
                if (i % j == 0) {
                    isFa = false;
                    break;
                }
            }
            if (isFa) {
                System.out.println(i);
            }
        }
    }
}

